{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a2095277-7c23-47d6-b2bc-a147f8fd013e",
   "metadata": {},
   "source": [
    "# 随机梯度下降"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f43b42b1-84de-4b20-82b4-0e8cec47a458",
   "metadata": {},
   "source": [
    "本节主要介绍随机梯度下降的主要内容\n",
    "\n",
    "首先导入随机梯度下降所需的minspore包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "40e63eca-ab32-44e5-9d34-7c80ec434b1e",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from mindspore import Tensor"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cfe2c14c-54f4-4ac9-86de-f60794c3a2b0",
   "metadata": {},
   "source": [
    "定义解析解，对参数进行计算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "7168e61b-9b2d-475b-8ceb-c9987133a62d",
   "metadata": {},
   "outputs": [],
   "source": [
    "def ols_algebra(x, y):\n",
    "    '''\n",
    "    解析解\n",
    "    '''\n",
    "    n = len(x)\n",
    "    w1 = (n*sum(x*y) - sum(x)*sum(y)) / (n*sum(x*x) - sum(x)*sum(x))\n",
    "    w0 = (sum(x*x)*sum(y) - sum(x)*sum(x*y)) / (n*sum(x*x) - sum(x)*sum(x))\n",
    "    \n",
    "    return w1,w0"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2cffbf2c-1051-4079-aa7c-f573144ed15b",
   "metadata": {},
   "source": [
    "通过最小二乘法定义梯度下降的算法过程。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "b99e7496-c7c6-4097-ae46-ad0c824c7329",
   "metadata": {},
   "outputs": [],
   "source": [
    "def ols_gradient_descent(x,y,lr,num_iter):\n",
    "    '''\n",
    "    梯度下降解\n",
    "    '''\n",
    "    w1 = 0\n",
    "    w0 = 0\n",
    "    for i in range(num_iter):\n",
    "        y_hat = (w1 * x)+ w0\n",
    "        w1_gradient = -2 * sum(x*(y-y_hat))\n",
    "        w0_gradient = -2*sum(y-y_hat)\n",
    "        w1 -=lr * w1_gradient\n",
    "        w0 -= lr* w0_gradient\n",
    "    return w1,w0"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "03e26d50-2b6f-4599-a89b-59464902ed89",
   "metadata": {},
   "source": [
    "使用plot函数对梯度下降结果进行绘图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "192c91c1-d51a-4753-9bc1-768ff67160f2",
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_pic(w1,w0,w1_,w0_,x,y):\n",
    "    '''\n",
    "    画图\n",
    "    '''\n",
    "    fig, axes = plt.subplots(1,2, figsize=(15,5))\n",
    "    w1 = w1.asnumpy()\n",
    "    w0 = w0.asnumpy()\n",
    "    w1_ = w1_.asnumpy()\n",
    "    w0_ = w0_.asnumpy()\n",
    "    x = x.asnumpy()\n",
    "    y = y.asnumpy()\n",
    "\n",
    "    axes[0].scatter(x,y)\n",
    "    axes[0].plot(np.array([50,110]), np.array([50,110])*w1 + w0, 'r')\n",
    "    axes[0].set_title('OLS')\n",
    "\n",
    "    axes[1].scatter(x,y)\n",
    "    axes[1].plot(np.array([50,110]), np.array([50,110])*w1_ + w0_, 'r')\n",
    "    axes[1].set_title('Gradient descent')\n",
    "\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4830a719-8996-4c2f-8518-e572405743d5",
   "metadata": {},
   "source": [
    "假设数据为自定义数据，x，y，经过解析，和最小二乘得到最终结果，最后使用绘图函数完成该过程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "3ede3073-bc74-4cec-855d-e8b5aadcece6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.7175629\n",
      "44.256042\n",
      "1.2633123\n",
      "0.12807482\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1080x360 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "x = np.array([55,71,68,87,101,87,75,78,93,73])\n",
    "y = np.array([91,101,87,109,129,98,95,101,104,93])\n",
    "\n",
    "x = Tensor(x.astype(np.float32))\n",
    "y = Tensor(y.astype(np.float32))\n",
    "\n",
    "w1,w0 = ols_algebra(x,y)\n",
    "print(w1)\n",
    "print(w0)\n",
    "\n",
    "w1_,w0_ = ols_gradient_descent(x,y,lr = 0.00001, num_iter = 500)\n",
    "print(w1_)\n",
    "print(w0_)\n",
    "\n",
    "plot_pic(w1,w0,w1_,w0_,x,y)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "MindSpore",
   "language": "python",
   "name": "mindspore"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
